#! /usr/bin/env python

#from builtins import breakpoint
from distutils.command.build import build
import logging
from openpyxl import load_workbook
#from optparse import OptionParser 
import argparse
import copy, json,re, os, commands
import shutil
import logging
import collections
import sys
import inspect
import random
import threading
import time
reload(sys)
sys.setdefaultencoding('utf-8')

typeRE=re.compile(r'[a-zA-Z]')

class MODULE:
    pass

class SUITE:
    pass

class GROUP:
    pass

class TEST:
    pass

class OPTION:
    pass

class MACRO:
    pass

class TestCase(object):
    pass

class TestEncoder(json.JSONEncoder):
    '''
        testcase object transfer to JSON
        '''
    def default(self, obj):
        d={}
        d.update(obj.__dict__)
        return d

bid_re=re.compile('(?<=Job <)[0-9]*(?=>)')

CompOptsKeywords = [
                    "RTLFilelist",
                    "VIPFilelist",
                    "TBFilelist",
                    "RTLCompOpt", 
                    "VIPCompOpt",
                    "TBCompOpt",
                    "ElabOpt",
                    "UcliOpt",
                    "PassCfg",
                    "FailCfg",
                    "IgnoreCfg",
                    "CheckRules",
                    "BaseExtends"
                    ] 

TestOptsKeywords = {
  #"A": "Name", 
  "B": "UvmTestName", 
  "C": "CtestName", 
  "D": "SimOpts", 
  "E": "CtestOpts", 
  "F": "Category", 
  "G": "Seeds" 
}

KeyMapOverride = {
    "rtl" : "RTLFilelist", 
    "tb"  : "TBFilelist", 
    "vip" : "VIPFilelist", 
    "tcl" : "UcliOpt", 
    "pass_cfg" : "PassCfg", 
    "fail_cfg" : "FailCfg", 
    "ignore_cfg" : "IgnoreCfg", 
    "checkfile" : "CheckRules", 
}

KeyMapTestOpts = {
   "uvm_testname" : "UvmTestName",  
   "ctest_name" : "CtestName",
   "sim_args" : "SimOpts",
   "cflags" : "CtestOpts",
   "category" : "Category",
   "seed" : "Seeds"
}

KeyMapNoOverride = {
    "rtl_comp_opts" : "RTLCompOpt", 
    "vip_comp_opts" : "VIPCompOpt", 
    "tb_comp_opts" : "TBCompOpt", 
    "elab_comp_opts" : "ElabOpt", 
}




class TOKEN:
  """for procedure control when solving the TEST sheet """
  def __init__(self):
    self.group_start = False 
    self.test_start = False 
    self.group_end = True 
    self.proc = "IDLE"
    self.logger =None
  
  def Group_start(self, value):
    self.group_start = value 

  def Group_end(self, value):
    self.group_end = value 

  def Test_start(self, value):
    self.test_start = value 
  
  def Proc(self):
    if not self.group_start and not self.test_start and self.group_end:
      self.proc = "DONE"

    elif self.group_start and not self.test_start and not self.group_end:
      self.proc = "SOLVEG"

    elif self.group_start and self.test_start and not self.group_end:
      self.proc = "SOLVET"
    else:
       self.logger.debug("group_start : %s, test_start : %s, self.group_end : %s"%\
                    (self.group_start, self.test_start, self.group_end))
       assert False, "illegal status"

    return self.proc


class TestEncoder(json.JSONEncoder):
    '''
        testcase object transfer to JSON
        '''
    def default(self, obj):
        d={}
        d.update(obj.__dict__)
        return d

class RunSim(object):

    def __init__(self):
        self.SetArgsLogger()
        self.GetEnv()
        self.top=self.GetModules()
        self.GenJson()
        self.regression_home = os.getcwd()
        self.makefiles = "%s/Makefile"%(self.tools_home)
        self.GetTestDB()
        self.__grouptask={}
        self.bids=[]
        self.__taskstatus = {}

    def GetEnv(self):
        assert "VERI_HOME" in os.environ, "VERIFICATION HOME not set"
        assert "TESTPLAN_HOME" in os.environ, " TESTPLAN_HOME not set"
        assert "TEST_HOME" in os.environ, "TEST_HOME not set"
        assert "TOOLS_HOME" in os.environ, "TOOLS_HOME not se"
        if "TEST_PARALLEL_NUN" in os.environ:
            self.parallel_num = os.environ.get("PARALLEL_HOME")
        else:
            self.parallel_num = 8

        self.tb_home= os.environ.get("VERI_HOME")
        self.testplan_home = os.environ.get("TESTPLAN_HOME")
        self.test_home = os.environ.get("TEST_HOME")
        self.tools_home = os.environ.get("TOOLS_HOME")
        #self.regression_home = self.tb_home
        planname = "%s/%s_Test_Plan.xlsx"%(self.testplan_home, self.args.Module) 
        self.wb = load_workbook(filename = planname)
        #to Do
        worklist = self.wb.get_sheet_names()
        sheet_ranges = self.wb["ReadMe"]
        self.worklist = self.wb.get_sheet_names()
        assert len(self.worklist)!=0, "empty testplan from you set : %s"%(planname) 
        assert "ReadMe" in self.worklist, "no ReadMe sheet in testplan : %s"%(planname) 
        assert "GlobalDefines" in self.worklist, "no GlobalDefines sheet in testplan : %s"%(planname) 
        assert "CompileOption" in self.worklist, "no CompileOption in testplan : %s"%(planname) 
        havetest = ("UnitTest" in self.worklist) or ("IntegrationTest" in self.worklist) or ("SystemTest" in self.worklist) or \
                   ("GateLevelTestself." in self.worklist) or ("EmuTest" in self.worklist)
        assert havetest, "no test in testplan : %s"(planname)

    def SetArgsLogger(self):
       parser = argparse.ArgumentParser(description='EzChip Testbench FLow self.args Parser')
       parser.add_argument('-t', '--test', nargs="+", dest="testlib", \
                         help="give the test list that should be run")
       parser.add_argument('-g', '--group', nargs='+', dest="grouplib", \
                         help="give the group list that should be run")
       parser.add_argument('-v', '--verdi', action='store_true', dest="waveform", default=False, \
                         help="enable dump the simulation waveform")
       parser.add_argument('-n', '--num', action='store', type=int, dest="iteration_num", default=1, \
                         help="the iteration num of ")
       parser.add_argument('-c', '--comp', action='store_true', dest="compile", default=False, 
                         help="enable compile work")
       parser.add_argument('-s', '--sim', action='store_true', dest="sim", default=False, \
                         help="enable simulation work")
       parser.add_argument('-d', '--debug', action='store_true', dest="debug", default=False, \
                         help="enable debug mode")
       parser.add_argument('-l', '--list', action='store_true', dest="list", default=False, \
                         help="list all the test in the testplan")
       parser.add_argument('--gls', action='store_true', dest="gls", default=False, \
                         help="Enable Gatelevel Sim")
       parser.add_argument('--cov',  action='store_true', dest="cov", default=False, \
                         help="Enable Dump Coveage ")
       parser.add_argument('--cov_opt',  nargs='+', dest="cov_opt", \
                         help="add coverage options")
       parser.add_argument('--covmerge',  nargs='+', dest="covmerge", \
                         help="merge coverage")
       parser.add_argument('--seed', action='store', dest="seed", default=None, \
                         help="give the seed")
       parser.add_argument('--log', action='store_true', dest="log", default=False, \
                         help="open test log")
       parser.add_argument('--check', action='store_true', dest="check", default=None, \
                         help="check test log")
       parser.add_argument('--clean', action='store_true', dest="clean", default=False, \
                         help="clean test")
       parser.add_argument('-q', '--quiet', action='store_true', dest="quiet", default=False, \
                         help="enable quiet mode")
       parser.add_argument('-fsdb', '--fsdb', action='store_true', dest="fsdb", default=False, \
                         help="enable fsdb Dump")
       parser.add_argument("-m", "--module", action="store", default=None, dest='Module', \
                         help="set the module top  name to find the corresponded testplan ")
       parser.add_argument("--suite", action="store", default='ut', dest="Suite", \
                         help="set the testsuit type for regression")
       parser.add_argument("--tool", action="store", default='snps', dest="Tools", \
                         help="set the tools vendor")
       parser.add_argument("--ctool", action="store", default='snps', dest="cTools", \
                         help="set the toolchain vendor")
       #parser.add_argument("-t", "--template", action="store", default="lsu.template", dest="Template", \
       #                  help="specify the template files")
       parser.add_argument("--genjson", action="store_true", default=True, dest="GenJSON", \
                         help="generate the json from excel testplan")
       parser.add_argument("-j", "--usejson", action="store_true", default=False, dest="JSON", \
                         help="get the testdb info from JSON files")
       parser.add_argument("--lsf", action="store_true", default=False, dest="LSF", \
                         help="set lsf mode for regression")
       parser.add_argument("--cat", action="store", default=None, dest="Category", \
                         help="set lsf mode for regression")
       parser.add_argument("--genctest", action="store_true", default=False, dest="GenCtest", \
                         help="set lsf mode for regression")
       self.args=parser.parse_args()
    
       self.logger = logging.getLogger(__name__)
    
       if self.args.debug: 
         log_mode = logging.DEBUG
       else:
         log_mode = logging.INFO
       self.logger.setLevel(level = log_mode)
       
       handler = logging.FileHandler("neorun.log.")
       handler.setLevel(log_mode)
       formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
       handler.setFormatter(formatter)
        
       console = logging.StreamHandler()
       console.setLevel(log_mode)
        
       self.logger.addHandler(handler)
       self.logger.addHandler(console)
       
       if self.args.log:
          assert self.args.seed!=None, "please give the seed for open sim log"
       if self.args.debug:
           logging.debug(self.args)
       if not self.args.JSON:
           assert self.args.Module !=None, "Please specify a Testplan for this tools"

    def SolveReadMe(self):
        sheet_ranges = self.wb["ReadMe"]
        column=len(sheet_ranges['A'])
        line=len(sheet_ranges['1'])
        assert  column != 0, "no contents in sheets column"
        assert  line != 0, "no contents in sheets line"
    
        for i in range(1, column+1):
          if sheet_ranges["A%s"%(i)].value.strip(" ") == "TopName":
            modulename = sheet_ranges["B%s"%(i)].value.strip(" ") 
            break
        assert modulename !=None, "No Module Name set in ReadMe of testplan %s"%()
        assert modulename == self.args.Module, "Moudle Name mismach : input : %s, testplan : %s"(modulename, self.args.Module)
        top = MODULE()
        setattr(top, "name", modulename)
        return top
    
    def SolveGlobalDefines(self):
        macros = {}
        sheet_ranges = self.wb["GlobalDefines"]
        column=len(sheet_ranges['A'])
        line=len(sheet_ranges['1'])
        assert  column != 0, "no contents in sheets column"
        assert  line != 0, "no contents in sheets line"
    
        start = 0
        for i in range(1, column+1):
          if sheet_ranges["A%s"%(i)].value.strip(" ") == "Macros":
            start = i+1
            break
        assert  start != 0, "GlobalDefines sheet was empty in testplan %s"%(self.args.Module)
    
        for i in range(start, column+1):
          if sheet_ranges["A%s"%(i)].value != None:
            name = sheet_ranges["A%s"%(i)].value.strip(" ") 
            value = sheet_ranges["B%s"%(i)].value.strip(" ").split(";")
            macro = MACRO()
            setattr(macro, "name", name)
            setattr(macro, "value", value)
            macros[name] = macro
        return macros 
            
    def SolveCompileOption(self):
        compileopts = {}
        elabopts = {}
        cflagsopts = {}
        sheet_ranges = self.wb["CompileOption"]
        column=len(sheet_ranges['A'])
        line=len(sheet_ranges['1'])
        assert  column != 0, "no contents in sheets column"
        assert  line != 0, "no contents in sheets line"
    
        start = 0
        for i in range(1, column+1):
          if sheet_ranges["A%s"%(i)].value.strip(" ") == "CompileOpts":
            start = i+2
            break
        assert  start != 0, "CompileOpts sheet has no CompileOpts in testplan %s"%(self.args.Module)
    
        for i in range(start, column+1):
          if sheet_ranges["A%s"%(i)].value != None:
            name  = sheet_ranges["A%s"%(i)].value.strip(" ") 
            tool = sheet_ranges["B%s"%(i)].value.strip(" ")
            if sheet_ranges["C%s"%(i)].value != None:
              value = sheet_ranges["C%s"%(i)].value.strip(" ").split(";")
            else:
              value = []
            if sheet_ranges["D%s"%(i)].value!= None:
              extend = sheet_ranges["D%s"%(i)].value.strip(" ").split(";")
            else: 
              extend = None
            assert  tool != None, "no tool set contents in sheets option %s"%(name)
            assert  len(value) !=0 , "no contents in sheets option %s"%(name)
            opt = OPTION()
            setattr(opt, "name", name)
            setattr(opt, "value", value)
            setattr(opt, "tool", tool)
            setattr(opt, "extend", extend)
            setattr(opt, "_type", "Comp")
            compileopts[name] = opt
          else:
            start = start+1
            break
    
        for i in range(start, column+1):
          if sheet_ranges["A%s"%(i)].value != None:
            if sheet_ranges["A%s"%(i)].value.strip(" ") == "ElabOpts":
              start = i+2
              break
        assert  start != column, "ElabOpts sheet has no CompileOpts in testplan %s"%(self.args.Module)
    
        for i in range(start, column+1):
          if sheet_ranges["A%s"%(i)].value != None:
            name  = sheet_ranges["A%s"%(i)].value.strip(" ") 
            tool = sheet_ranges["B%s"%(i)].value.strip(" ")
            value = sheet_ranges["C%s"%(i)].value.strip(" ").split(";")
            if sheet_ranges["D%s"%(i)].value!= None:
              extend = sheet_ranges["D%s"%(i)].value.strip(" ").split(";")
            else: 
              extend = None
            assert  tool != None, "no tool set contents in sheets option %s"%(name)
            assert  len(value) !=0 , "no contents in sheets option %s"%(name)
            opt = OPTION()
            setattr(opt, "name", name)
            setattr(opt, "value", value)
            setattr(opt, "tool", tool)
            setattr(opt, "extend", extend)
            setattr(opt, "_type", "Elab")
            elabopts[name] = opt
          else:
            start = start+1
            break
    
        for i in range(start, column+1):
          if sheet_ranges["A%s"%(i)].value == "CflagsOpts":
            start = i+2
            break
        
        if start < column:
          for i in range(start, column+1):
            if sheet_ranges["A%s"%(i)].value != None:
              name  = sheet_ranges["A%s"%(i)].value.strip(" ") 
              tool = sheet_ranges["B%s"%(i)].value.strip(" ")
              value = sheet_ranges["C%s"%(i)].value.strip(" ").split(";")
              if sheet_ranges["D%s"%(i)].value!= None:
                extend = sheet_ranges["D%s"%(i)].value.strip(" ").split(";")
              else: 
                extend = None
              assert  tool != None, "no tool set contents in sheets option %s"%(name)
              assert  len(value) !=0 , "no contents in sheets option %s"%(name)
              opt = OPTION()
              setattr(opt, "name", name)
              setattr(opt, "value", value)
              setattr(opt, "tool", tool)
              setattr(opt, "extend", extend)
              setattr(opt, "_type", "Cflags")
              cflagsopts[name] = opt
            else:
              start = start+1
    
        return compileopts, elabopts, cflagsopts 

    def SolveTest(self, sheet_name):
        suite = SUITE()
        sheet_ranges = self.wb[sheet_name]
        column=len(sheet_ranges['A'])
        line=len(sheet_ranges['1'])
        assert  column != 0, "no contents in sheets column"
        assert  line != 0, "no contents in sheets line"
        setattr(suite, "groups", collections.OrderedDict())
    
        token = TOKEN()
        token.logger = self.logger
        for i in range(1, column+1):
          
          if sheet_ranges["A%s"%(i)].value == "Groups" and token.Proc() == "DONE":
            gname =  sheet_ranges["B%s"%(i)].value.strip(" ")
            assert  gname != None, "no group name set  in sheets testsuite %s at line %s"%(sheet_name, i)
            group = GROUP() 
            setattr(group, "name", gname)
            setattr(group, "tests", {})
            token.Group_start(True)
            token.Group_end(False)
            suite.groups[gname] = copy.deepcopy(group)
    
          elif token.Proc() == "SOLVEG" and sheet_ranges["A%s"%(i)].value == "Tests":
            token.Test_start(True)
    
          elif token.Proc() == "SOLVEG" and sheet_ranges["B%s"%(i)].value != None:
            label = sheet_ranges["B%s"%(i)].value.strip(" ")
            if sheet_ranges["C%s"%(i)].value !=None:
              value = sheet_ranges["C%s"%(i)].value.strip(" ").split(";")
            else:
              value = None
            if label in CompOptsKeywords: 
              setattr(suite.groups[suite.groups.keys()[-1]], label, value)
    
          elif token.Proc() == "SOLVET" and sheet_ranges["A%s"%(i)].value == "Name":
            #setattr(group, )
            continue
    
          elif token.Proc() == "SOLVET" and (sheet_ranges["A%s"%(i)].value != "Name" and sheet_ranges["A%s"%(i)].value !=None):
            test = TEST()
            name = sheet_ranges["A%s"%(i)].value.strip(" ")
            setattr(test, "name", name) 
            for j in TestOptsKeywords.keys():
              if TestOptsKeywords[j] == "SimOpts" or TestOptsKeywords[j] == "CtestOpts" or TestOptsKeywords[j] == "Category": 
                if sheet_ranges["%s%s"%(j, i)].value !=None:
                  value = sheet_ranges["%s%s"%(j, i)].value.strip(" ").split(";")
                  setattr(test, TestOptsKeywords[j], value)
                else:
                  setattr(test, TestOptsKeywords[j], None)
              else:
                if sheet_ranges["%s%s"%(j, i)].value !=None:
                  value = str(sheet_ranges["%s%s"%(j, i)].value).strip(" ")
                  setattr(test, TestOptsKeywords[j], value)
                else:
                  setattr(test, TestOptsKeywords[j], None)
            suite.groups[suite.groups.keys()[-1]].tests[name] =  copy.deepcopy(test)
    
          elif token.Proc() == "SOLVEG" and sheet_ranges["B%s"%(i)].value == None:
            continue
    
          elif token.Proc() == "SOLVET" and sheet_ranges["B%s"%(i)].value == None:
            token.Group_start(False)
            token.Test_start(False)
            token.Group_end(True)
          elif sheet_ranges["A%s"%(i)].value == "Groups" and token.Proc() == "SOLVET":
            gname =  sheet_ranges["B%s"%(i)].value.strip(" ")
            assert  gname != None, "no group name set  in sheets testsuite %s at line %s"%(sheet_name, i)
            group = GROUP() 
            setattr(group, "name", gname)
            setattr(group, "tests", {})
            token.Group_start(True)
            token.Group_end(False)
            suite.groups[gname] = copy.deepcopy(group)
    
        return suite
            
    def SolveUnitTest(self):
      return self.SolveTest("UnitTest")
    
    def SolveIntegrationTest(self):
      return self.SolveTest("IntegrationTest")
    
    def SolveSystemTest(self):
      return self.SolveTest("SystemTest")
    
    def SolveGateLevelTest(self):
      return self.SolveTest("GateLevelTest")
    
    def SolveEMUTest(self):
      return self.SolveTest("EmuTest")
    
    def GetModules(self):
        module=self.SolveReadMe()
    
        setattr(module, "macros", self.SolveGlobalDefines())
    
        comp, elab, cflag = self.SolveCompileOption()
        setattr(module, "CompileOpts", comp)
        setattr(module, "ElabOpts", elab)
        setattr(module, "CflagsOpts", cflag)
    
        setattr(module, "ut", self.SolveUnitTest())
        setattr(module, "it", self.SolveIntegrationTest())
        setattr(module, "st", self.SolveSystemTest())
        setattr(module, "gls", self.SolveGateLevelTest())
        setattr(module, "emu", self.SolveEMUTest())
    
        return module
    
    def GenJson(self):
        if self.args.GenJSON:
           json_content = TestEncoder().encode(self.top)
           json_file = "%s/%s_Test_Plan.json"%(self.testplan_home, self.args.Module)
           if os.path.isfile(json_file):
             os.remove(json_file)
           json_content = json.loads(json_content)
           json_content=json.dumps(json_content, indent=2)
           with open(json_file, "w+") as f:
                 f.write(json_content)
    
    def GetDefine(self, value):
        if value == None:
          return None 
        ret = ''
        if r"`" in str(value):
          define = value.strip("`")
          assert define in self.top.macros.keys(), "No Define named : %s in your testplan"%(define)
          macro_value = self.top.macros[define].value 
          if isinstance(macro_value, list):
             for i in macro_value:
                ret="%s %s"%(ret, self.GetDefine(i))
          else:
            ret="%s %s"%(ret, self.GetDefine(macro_value))
        else:
          ret = value
        return ret
                
    def GetOption(self, value, get_opt=False):
        ret = ''
        if get_opt:
          find_opt =False
          if value in self.top.CompileOpts.keys():
            find_opt = True
            options = self.top.CompileOpts
          elif value in self.top.ElabOpts.keys():
            find_opt = True
            options = self.top.ElabOpts
          elif value in self.top.CflagsOpts.keys():
            find_opt = True
            options = self.top.CflagsOpts
          assert find_opt, "No Option named : %s in your testplan"%(value)

          element = options[value]
          if element._type != "Cflags":
            assert element.tool == self.args.Tools, "Tool vendor not match-- set : %s, you want %s"%(element.tool, self.args.Tools)
          optvalue = element.value
          if isinstance(optvalue, list):
              for i in optvalue:
                ret = "%s %s"%(ret, self.GetDefine(i))
          else: 
              ret = "%s %s"%(ret, self.GetDefine(optvalue))
          if element.extend != None:
              if isinstance(element.extend, list):
                for ee in element.extend:
                  ret = "%s %s"%(ret, self.GetOption(ee, True))
              else:
                ret = "%s %s"%(ret, self.GetOption(element.extend, True))
        else: 
          if value == None:
            return None

          if "+OPT" in str(value):
            opt = value.replace(" ","").split("=")[-1]
            find_opt =False
            if opt in self.top.CompileOpts.keys():
              find_opt = True
              options = self.top.CompileOpts
            elif opt in self.top.ElabOpts.keys():
              find_opt = True
              options = self.top.ElabOpts
            elif opt in self.top.CflagsOpts.keys():
              find_opt = True
              options = self.top.CflagsOpts
            assert find_opt, "No Option named : %s in your testplan"%(value)

            element = options[opt]
            if element._type != "Cflags":
              assert element.tool == self.args.Tools, "Tool vendor not match-- set : %s, you want %s"%(element.tool, self.args.Tools)
            optvalue = element.value
            if isinstance(optvalue, list):
                for i in optvalue:
                  ret = "%s %s"%(ret, self.GetDefine(i))
            else: 
                ret = "%s %s"%(ret, self.GetDefine(optvalue))
            if element.extend != None:
                if isinstance(element.extend, list):
                  for ee in element.extend:
                    ret = "%s %s"%(ret, self.GetOption(ee, True))
                else:
                  ret = "%s %s"%(ret, self.GetOption(element.extend, True))
          else:
              ret = "%s %s"%(ret, self.GetDefine(value))
        return ret
            
    def SolveDB(self, value):
        ret=""
        if isinstance(value, list):
            for i in value:
              ret_i=''
              ret_i = self.GetDefine(i)
              ret_i = self.GetOption(ret_i)
              ret = "%s %s"%(ret, ret_i)
        else:
            ret = self.GetDefine(value)
            ret = self.GetOption(ret)
        if ret != None:
          ret = os.path.expandvars(ret)
        return ret

    def SolveGroup(self, group, name):
        
        if group.BaseExtends != None:
            value = group.BaseExtends 
            if isinstance(value, list):
               for i in value:
                  find_group = False
                  if i in self.top.ut.groups.keys():
                    find_group = True
                    self.SolveGroup(self.top.ut.groups[i], name) 
                  elif i in self.top.it.groups.keys():
                    find_group = True
                    self.SolveGroup(self.top.it.groups[i], name) 
                  elif i in self.top.st.groups.keys():
                    find_group = True
                    self.SolveGroup(self.top.st.groups[i], name) 
                  elif i in self.top.gls.groups.keys():
                    find_group = True
                    self.SolveGroup(self.top.gls.groups[i], name) 
                  elif i in self.top.emu.groups.keys():
                    find_group = True
                    self.SolveGroup(self.top.emu.groups[i], name) 
                  assert find_group, "no group : %s found in testplan "%(i)
            else:
                if value in self.top.ut.groups.keys():
                  find_group = True
                  self.SolveGroup(self.top.ut.groups[value], name) 
                elif value in self.top.it.groups.keys():
                  find_group = True
                  self.SolveGroup(self.top.it.groups[value], name) 
                elif value in self.top.st.groups.keys():
                  find_group = True
                  self.SolveGroup(self.top.st.groups[value], name) 
                elif value in self.top.gls.groups.keys():
                  find_group = True
                  self.SolveGroup(self.top.gls.groups[value], name) 
                elif value in self.top.emu.groups.keys():
                  find_group = True
                  self.SolveGroup(self.top.emu.groups[value], name) 
            
                assert find_group, "no group : %s found in testplan "%(value)
                
        for j in KeyMapOverride.keys():
            if KeyMapOverride[j] in group.__dict__.keys():
               self.testdb[name][j] = self.SolveDB(group.__dict__[KeyMapOverride[j]])

        for j in KeyMapNoOverride.keys():
            if KeyMapNoOverride[j] in group.__dict__.keys():
               if j in self.testdb[name].keys():
                 self.testdb[name][j] = "%s %s"%(self.testdb[name][j] ,self.SovleDB(group.__dict__[KeyMapNoOverride[j]]))
               else :
                 self.testdb[name][j] = self.SolveDB(group.__dict__[KeyMapNoOverride[j]])
        
        # get the test
        if not "test" in self.testdb[name].keys():
            self.testdb[name]["test"] = {}
        if hasattr(group, "tests"):
          if len(group.tests.keys()):
            for tt in group.tests: 
                self.testdb[name]["test"][tt] = {}
                for kk in KeyMapTestOpts.keys(): 
                    self.testdb[name]["test"][tt]["name"] = tt
                    self.testdb[name]["test"][tt][kk] = self.SolveDB(group.tests[tt].__dict__[KeyMapTestOpts[kk]])

    def GetTestDB(self):

        #get the testplan
        self.testdb = {}
        if self.args.JSON:
            json_files = "%s/%_Test_Plan.json"%self.test_home
            assert os.path.isfile(json_files), "No files under the path :  %s"%(json_files)
            f = open(json_files, "r")
            self.top = json.load(f)

        #build the testdb
        ss = self.top.__dict__[self.args.Suite] 
        for gg in ss.groups.keys():
          group = ss.groups[gg]
          self.testdb[gg] = {}
          self.SolveGroup(group, gg)
          
          for j in KeyMapOverride.keys():
            assert j in self.testdb[gg].keys(), "no %s set"%(KeyMapOverride[j])
            assert self.testdb[gg][j] !=None , "%s value was None"%(KeyMapOverride[j])

            '''
          for j in KeyMapNoOverride.keys():
            if j in self.testdb[gg].keys():
               assert self.testdb[gg][j] !=None , "%s value was None"%(KeyMapNoOverride[j])
               '''

    def Run(self):
        if self.args.list:
            self.GetList()
        elif self.args.GenCtest:
          self.GenCtest()
        else:
            self.GetTest()
            if self.args.waveform:
                self.MakeVerdi()
            if self.args.check:
                self.__CheckLog()
                self.PrintLog()
            elif self.args.log or self.args.covmerge or self.args.clean:
                self.__DoMiscOp()
            else:
                self.BuildDIR()
                if (not self.args.compile) and (not self.args.sim):  
                    self.BuildTB()
                    self.RunTest()
                    self.PrintLog()
                else:
                    if self.args.compile:
                        self.BuildTB()
                    if self.args.sim:
                        self.RunTest()
                        self.PrintLog()


    def GenCtest(self):
      basetest="tpe_mma_sg_int8_out32_smem_sanity_test"
      testhome="%s/fw/tests"%os.environ.get("VERI_HOME")
      template = "%s/%s"%(testhome, basetest)
      for g in self.testdb.keys():
        for t in self.testdb[g]["test"].keys():
           if self.testdb[g]['test']["ctest_name"] != None:
              ctest="%s/%s"(testhome, self.testdb[g]['test'][t]["ctest_home"].strip())
              if ctest==template:
                pass
              elif os.path.isdir(ctest):
                pass
              else:
                shutil.copytree(template, ctest)


    def GetList(self):
        testinfo="""
 ************************************************
                 Testcase List 
 ************************************************
 """
        for g in self.testdb.keys():
            testinfo+='''
%s:'''%(g)
            for t in self.testdb[g]['test'].keys():
                testinfo+='''
    %s'''%(t)
        self.logger.info(testinfo)

    def __DoMiscOp(self):
        __name = self.tasklist.keys()[0]
        __task = self.tasklist[__name]
        cmd = self.GetCmd(__task)
        os.system(cmd)

    def __CheckLog(self):
        for i in self.tasklist.keys():
          __task = self.tasklist[i]
          #FIXME
          self.CheckResult(__task)
          self.__taskstatus[i] = 1

    def GetTest(self):
        # no -g or  -t
        self.tasklist={}
        if (not self.args.grouplib) and (not self.args.testlib):

            for i in self.testdb.keys():
                g = i
                __group = g
                __comp_dir = "%s/build/%s/compile"%(self.regression_home, g)
                __cov_dir = "%s/build/%s/cov"%(self.regression_home, g)
                __rtl_file = self.testdb[g]["rtl"]
                __tb_file = self.testdb[g]["tb"]
                __vip_file = self.testdb[g]["vip"]
                __rtl_compt_opt = self.testdb[g]["rtl_comp_opts"]
                __tb_compt_opt = self.testdb[g]["tb_comp_opts"]
                __vip_compt_opt = self.testdb[g]["vip_comp_opts"]
                __elab_compt_opt = self.testdb[g]["elab_comp_opts"]
                __checkfiles = self.testdb[g]["checkfile"]
                __pass_cfg = self.testdb[g]["pass_cfg"]
                __fail_cfg = self.testdb[g]["fail_cfg"]
                __ignore_cfg = self.testdb[g]["ignore_cfg"]
                __tcl = self.testdb[__group]['tcl']
                for t in self.testdb[g]['test'].keys():
                    for itnum in range(0, self.args.iteration_num):
                        if self.args.seed == None: 
                          if self.args.iteration_num>1:
                            __seed = random.randint(0, 2**32) 
                          else:
                            if self.testdb[g]["test"][t]["seed"] != None:
                              __seed = self.testdb[g]["test"][t]["seed"].strip(' ')
                            else:
                              __seed = random.randint(0, 2**32) 
                        else:
                            assert self.args.iteration_num ==1; "you cant give the same seed for two case in iteration simulation"
                            __seed = self.args.seed 
                        test = TestCase()
                        setattr(test, "seed", __seed)
                        __sim_dir = "%s/build/%s/sim/%s/%s"%(self.regression_home, g, t, str(__seed))
                        setattr(test, "group", __group)
                        setattr(test, "name", t)
                        setattr(test, "comp_dir", __comp_dir)
                        setattr(test, "sim_dir", __sim_dir)
                        setattr(test, "cov_dir", __cov_dir)
                        setattr(test, "rtl_file", __rtl_file)
                        setattr(test, "tb_file", __tb_file)
                        setattr(test, "vip_file", __vip_file)
                        setattr(test, "rtl_comp_opts", __rtl_compt_opt)
                        setattr(test, "tb_comp_opts", __tb_compt_opt)
                        setattr(test, "vip_comp_opts", __vip_compt_opt)
                        setattr(test, "elab_comp_opts", __elab_compt_opt)
                        setattr(test, "checkfiles", __checkfiles)
                        setattr(test, "pass_cfg", __pass_cfg)
                        setattr(test, "fail_cfg", __fail_cfg)
                        setattr(test, "ignore_cfg", __ignore_cfg)
                        setattr(test, "tcl", __tcl)

                        assert "uvm_testname" in self.testdb[g]["test"][t].keys(), "%s have not set a uvm_testname"%(t)
                        setattr(test, "uvm_testname", self.testdb[g]["test"][t]['uvm_testname'])
                        if "tcl" in self.testdb[g]["test"][t].keys():
                            setattr(test, "tcl", self.testdb[g]["test"][t]['tcl'])
                        if "ctest_name" in self.testdb[g]["test"][t].keys():
                            setattr(test, "ctest_name", self.testdb[g]["test"][t]['ctest_name'])
                        if "sim_args" in self.testdb[g]["test"][t].keys():
                            setattr(test, "sim_args", self.testdb[g]["test"][t]['sim_args'])
                        if "uvm_timeout" in self.testdb[g]["test"][t].keys():
                            setattr(test, "uvm_timeout", self.testdb[g]["test"][t]['uvm_timeout'])
                        if "cflags" in self.testdb[g]["test"][t].keys():
                            setattr(test, "cflags", self.testdb[g]["test"][t]['cflags'])
                        if "catgory" in self.testdb[g]["test"][t].keys():
                            setattr(test, "catgory", self.testdb[g]["test"][t]['catgory'])
                        self.tasklist["%s_%s"%(t, itnum)] = copy.deepcopy(test)
            if self.args.debug:
                self.logger.debug(self.tasklist)
            #assert False, "group name/test name must be set for simualtion"
            #permit all regression
        # no -g but  -t
        elif (not self.args.grouplib) and len(self.args.testlib)!=0:
            assert False, "test name must be set with group name"

        # no -t but  -g
        elif len(self.args.grouplib) !=0 and (not self.args.testlib):
            for i in self.args.grouplib:
                assert i in self.testdb.keys(), "NO Group named %s in TestDB"%(i)
                g = i
                __group = g
                __comp_dir = "%s/build/%s/compile"%(self.regression_home, g)
                __cov_dir = "%s/build/%s/cov"%(self.regression_home, g)
                __rtl_file = self.testdb[g]["rtl"]
                __tb_file = self.testdb[g]["tb"]
                __vip_file = self.testdb[g]["vip"]
                __rtl_compt_opt = self.testdb[g]["rtl_comp_opts"]
                __tb_compt_opt = self.testdb[g]["tb_comp_opts"]
                __vip_compt_opt = self.testdb[g]["vip_comp_opts"]
                __elab_compt_opt = self.testdb[g]["elab_comp_opts"]
                __checkfiles = self.testdb[g]["checkfile"]
                __pass_cfg = self.testdb[g]["pass_cfg"]
                __fail_cfg = self.testdb[g]["fail_cfg"]
                __ignore_cfg = self.testdb[g]["ignore_cfg"]
                __tcl = self.testdb[__group]['tcl']
                for t in self.testdb[g]['test'].keys():
                    for itnum in range(0, self.args.iteration_num):
                        if self.args.seed == None: 
                          if self.args.iteration_num>1:
                            __seed = random.randint(0, 2**32) 
                          else:
                            if self.testdb[g]["test"][t]["seed"] != None:
                              __seed = self.testdb[g]["test"][t]["seed"].strip(' ')
                            else:
                              __seed = random.randint(0, 2**32) 
                        else:
                            assert self.args.iteration_num == 1; "you cant give the same seed for two case in iteration simulation"
                            __seed = self.args.seed 
                        test = TestCase()
                        setattr(test, "seed", __seed)
                        __sim_dir = "%s/build/%s/sim/%s/%s"%(self.regression_home, g, t, str(__seed))
                        setattr(test, "group", __group)
                        setattr(test, "name", t)
                        setattr(test, "comp_dir", __comp_dir)
                        setattr(test, "sim_dir", __sim_dir)
                        setattr(test, "cov_dir", __cov_dir)
                        setattr(test, "rtl_file", __rtl_file)
                        setattr(test, "tb_file", __tb_file)
                        setattr(test, "vip_file", __vip_file)
                        setattr(test, "rtl_comp_opts", __rtl_compt_opt)
                        setattr(test, "tb_comp_opts", __tb_compt_opt)
                        setattr(test, "vip_comp_opts", __vip_compt_opt)
                        setattr(test, "elab_comp_opts", __elab_compt_opt)
                        setattr(test, "checkfiles", __checkfiles)
                        setattr(test, "pass_cfg", __pass_cfg)
                        setattr(test, "fail_cfg", __fail_cfg)
                        setattr(test, "ignore_cfg", __ignore_cfg)
                        setattr(test, "tcl", __tcl)

                        assert "uvm_testname" in self.testdb[g]["test"][t].keys(), "%s have not set a uvm_testname"%(t)
                        setattr(test, "uvm_testname", self.testdb[g]["test"][t]['uvm_testname'])
                        if "tcl" in self.testdb[g]["test"][t].keys():
                            setattr(test, "tcl", self.testdb[g]["test"][t]['tcl'])
                        if "ctest_name" in self.testdb[g]["test"][t].keys():
                            setattr(test, "ctest_name", self.testdb[g]["test"][t]['ctest_name'])
                        if "sim_args" in self.testdb[g]["test"][t].keys():
                            setattr(test, "sim_args", self.testdb[g]["test"][t]['sim_args'])
                        if "uvm_timeout" in self.testdb[g]["test"][t].keys():
                            setattr(test, "uvm_timeout", self.testdb[g]["test"][t]['uvm_timeout'])
                        if "cflags" in self.testdb[g]["test"][t].keys():
                            setattr(test, "cflags", self.testdb[g]["test"][t]['cflags'])
                        if "catgory" in self.testdb[g]["test"][t].keys():
                            setattr(test, "catgory", self.testdb[g]["test"][t]['catgory'])
                        self.tasklist["%s_%s"%(t, itnum)] = copy.deepcopy(test)
            if self.args.debug:
                self.logger.debug(self.tasklist)
        # have -g and  -t
        elif len(self.args.grouplib)*len(self.args.testlib) !=0:
           assert len(self.args.grouplib)==1, "more than one group be set for test"
           for i in self.args.testlib:
               __group = self.args.grouplib[0]
               __groupobj=self.testdb[self.args.grouplib[0]]
               assert i in __groupobj["test"].keys()
               __comp_dir = "%s/build/%s/compile"%(self.regression_home, __group)
               __cov_dir = "%s/build/%s/cov"%(self.regression_home, __group)
               __rtl_file = self.testdb[__group]["rtl"]
               __tb_file = self.testdb[__group]["tb"]
               __vip_file = self.testdb[__group]["vip"]
               __rtl_compt_opt = self.testdb[__group]["rtl_comp_opts"]
               __tb_compt_opt = self.testdb[__group]["tb_comp_opts"]
               __vip_compt_opt = self.testdb[__group]["vip_comp_opts"]
               __elab_compt_opt = self.testdb[__group]["elab_comp_opts"]
               __checkfiles = self.testdb[__group]["checkfile"]
               __pass_cfg = self.testdb[g]["pass_cfg"]
               __fail_cfg = self.testdb[g]["fail_cfg"]
               __ignore_cfg = self.testdb[g]["ignore_cfg"]
               __tcl = self.testdb[__group]['tcl']
               for itnum in range(0, self.args.iteration_num):
                    if self.args.seed == None: 
                        if self.args.iteration_num>1:
                          __seed = random.randint(0, 2**32) 
                        else:
                          if self.testdb[__group]["test"][i]["seed"] != None:
                            __seed = self.testdb[__group]["test"][i]["seed"].strip(" ")
                          else:
                            __seed = random.randint(0, 2**32) 
                    else:
                        assert self.args.iteration_num ==1; "you cant give the same seed for two case in iteration simulation"
                        __seed = self.args.seed 
                    test = TestCase()
                    setattr(test, "seed", __seed)
                    __sim_dir = "%s/build/%s/sim/%s/%s"%(self.regression_home, __group, i, str(__seed))
                    setattr(test, "group", __group)
                    setattr(test, "name", i)
                    setattr(test, "comp_dir", __comp_dir)
                    setattr(test, "sim_dir", __sim_dir)
                    setattr(test, "cov_dir", __cov_dir)
                    setattr(test, "rtl_file", __rtl_file)
                    setattr(test, "tb_file", __tb_file)
                    setattr(test, "vip_file", __vip_file)
                    setattr(test, "rtl_comp_opts", __rtl_compt_opt)
                    setattr(test, "tb_comp_opts", __tb_compt_opt)
                    setattr(test, "vip_comp_opts", __vip_compt_opt)
                    setattr(test, "elab_comp_opts", __elab_compt_opt)
                    setattr(test, "checkfiles", __checkfiles)
                    setattr(test, "pass_cfg", __pass_cfg)
                    setattr(test, "fail_cfg", __fail_cfg)
                    setattr(test, "ignore_cfg", __ignore_cfg)
                    setattr(test, "tcl", __tcl)

                    assert "uvm_testname" in self.testdb[__group]["test"][i].keys(), "%s have not bind to a  uvm_test"%(i)
                    setattr(test, "uvm_testname", self.testdb[__group]["test"][i]['uvm_testname'])
                    if "tcl" in self.testdb[__group]["test"][i].keys():
                        setattr(test, "tcl", self.testdb[__group]["test"][i]['tcl'])
                    if "ctest_name" in self.testdb[__group]["test"][i].keys():
                        setattr(test, "ctest_name", self.testdb[__group]["test"][i]['ctest_name'])
                    if "sim_args" in self.testdb[__group]["test"][i].keys():
                        setattr(test, "sim_args", self.testdb[__group]["test"][i]['sim_args'])
                    if "uvm_timeout" in self.testdb[__group]["test"][i].keys():
                        setattr(test, "uvm_timeout", self.testdb[__group]["test"][i]['uvm_timeout'])
                    if "cflags" in self.testdb[__group]["test"][i].keys():
                        setattr(test, "cflags", self.testdb[__group]["test"][i]['cflags'])
                    if "catgory" in self.testdb[__group]["test"][i].keys():
                        setattr(test, "catgory", self.testdb[__group]["test"][i]['catgory'])
                    self.tasklist["%s_%s"%(i, itnum)] = copy.deepcopy(test)
           if self.args.debug:
               self.logger.debug(self.tasklist[self.tasklist.keys()[0]].seed)

    def BuildDIR(self):
        for i in self.tasklist.keys():
            t = self.tasklist[i]
            if not os.path.exists(t.comp_dir):
                os.makedirs(t.comp_dir)
            if not os.path.exists(t.sim_dir):
                os.makedirs(t.sim_dir)

    def MakeVerdi(self):
        assert len(self.tasklist.keys()) == 1, "Only One case was permitted by verdi"
        name = self.tasklist.keys()[-1]
        t=self.tasklist[name]
        cmd = self.GetCmd(t)
        os.system(cmd)

    def __DoCompile(self, __task, __args, status):
        name = __task.group
        __cmd = self.GetCmd(__task, 1)
        __file = "%s/compile_shell"%(__task.comp_dir)
        __fp=open(__file, "w")
        __fp.write("#! /usr/bin/env bash\n")
        __fp.write(__cmd)
        __fp.close()
        os.system(__cmd)
        status[name] = 1
       
    def BuildTB(self):

        __thread_lib=[]
        self.build_bids={}
        if self.args.LSF:
          if len(self.tasklist.keys())>1:
            for i in self.tasklist:
                t = self.tasklist[i]
                if not (t.group in self.__grouptask.keys()):
                  self.__grouptask[t.group] = 0
                  self.build_bids[t.group] = self.openlava_submitter(t, t.group.name)
                  self.bids.append(self.build_bids[t.group])

            build_mon = threading.Thread(target=self.openlava_monitor, args=(self.build_bids, self.__grouptask, {}, {}, "comp"))
            build_mon.setDaemon(True)
            build_mon.start()
            build_mon.join(2)
          
        else:
          if len(self.tasklist.keys())>1:
             try:
                 for i in self.tasklist:
                     t = self.tasklist[i]
                     if not (t.group in self.__grouptask.keys()):
                         self.__grouptask[t.group] = 0
                         t = threading.Thread(target=self.__DoCompile, args=(t, self.args, self.__grouptask))
                         __thread_lib.append(t)
                         t.setDaemon(True)
                         t.start()
                 for t in __thread_lib:
                     t.join(2)
                     if not t.isAlive:
                        break
             except KeyboardInterrupt:
                 self.logger.info("Keyboard Interrupt Quit")
                 sys.exit(1)
          else:
            name = self.tasklist.keys()[0]
            t = self.tasklist[name]
            if not (t.group in self.__grouptask.keys()):
                self.__grouptask[t.group] = 0
                self.__DoCompile(t, self.args, self.__grouptask)

    def __DoSim(self, __task, __sema, __status, __taskstatus, __itername):
        __group =__task.group
        __cmd = self.GetCmd(__task)
        __file = "%s/run_shell"%(__task.sim_dir)
        __fp=open(__file, "w")
        __fp.write("#! /usr/bin/env bash\n")
        __fp.write(__cmd)
        __fp.close()
        wait_comp=0
        if (self.args.sim and self.args.compile) or\
           ((not self.args.sim) and (not self.args.compile)):
           wait_comp = 1
        if wait_comp:
            while(True):
                if __status[__group]:
                    break
            time.sleep(2)
        __taskstatus[__itername] = 0
        os.system(__cmd)
        self.CheckResult(__task)
        __taskstatus[__itername] = 1
        __sema.release()

    def openlava_job_status(self, status):
      
      headers=[]
      comments=[]
      st={}
      l=0
      for i in status.readlines():
        if l==0:
          headers=' '.join(i.split()).split()
          l=1
        else:
          comments=' '.join(i.split()).split()
    
      for i in range(len(headers)):
        st[headers[i]] = comments[i]
    
      return st['STAT']
    
    def openlava_submitter(self, task, bname, work="comp"):
      if work == "comp":
         name = task.group
         __cmd = self.GetCmd(task, 1)
         lsf_opt = '' 
         lsf_cmd = "bsub %s %s"%(lsf_opt, __cmd)
         self.logger.info(lsf_cmd)
         __file = "%s/compile_shell"%(task.comp_dir)
         __fp=open(__file, "w")
         __fp.write("#! /usr/bin/env bash\n")
         __fp.write(__cmd)
         __fp.close()
         (status, result) = commands.getstatusoutput(lsf_cmd)
         if bid_re.search(result):
           bid_m=bid_re.search(result)
           bid = bid_m.group()
         self.__grouptask[name] = 0
         return bid
      elif work == "sim":
         __group = task.group
         __cmd = self.GetCmd(task)
         __file = "%s/run_shell"%(task.sim_dir)
         wait_comp = 0
         if (self.args.sim and self.args.compile) or\
            ((not self.args.sim) and (not self.args.compile)):
            wait_comp = 1
         if wait_comp:
             while(True):
                 if self.__taskstatus[__group]:
                     break
             time.sleep(2)
         lsf_opt = '' 
         lsf_cmd = 'bsub %s %s'%(lsf_opt, __cmd)
         self.logger.info(lsf_cmd)
         (status, result) = commands.getstatusoutput(lsf_cmd)
         self.__taskstatus[bname] = 0
    
         if bid_re.search(result):
           bid_m=bid_re.search(result)
           bid = bid_m.group()

         __fp=open(__file, "w")
         __fp.write("#! /usr/bin/env bash\n")
         __fp.write(__cmd)
         __fp.close()
    
         return bid
      else:
        assert False, "illegal op %s "%(work)

    def openlava_monitor(self, groupbid, grouptask, testtasklist, teststatus, work='comp'):
    
      exception_status = [
      'EXIT',
      'UNKWN',
      'ZOMBI'
      ]
    
      onging_status = [
      'PEND',
      'PSUSP',
      'RUN',
      'USUSP',
      'SSUSP'
      ]
    
      if work == 'comp':

        while(1):
          for i in groupbid.keys():
            bid = groupbid[i]
            lsf_cmd ='bjobs %s'%(bid)
            status_info = os.popen(lsf_cmd)
            Status = self.openlava_job_status(status_info)
            if Status in exception_status:
              assert False,"\033[31;1m: Compile in openlava enconter LSF error : \033[0m %s"%(i)
            elif Status in onging_status: 
              pass
            elif Status == 'DONE':
              grouptask[i] = 1
            
          breakcondition = 1
          for i in grouptask.keys():
            breakcondition *= grouptask[i]
          
          if breakcondition:
            break

          time.sleep(2)
      
      elif work == 'sim':
    
        while(1):
           for i in testtasklist.keys(): 
             seed    = testtasklist[i].seed
             sim_dir = testtasklist[i].sim_dir 
             bid     = testtasklist[i].bid
    
             lsf_cmd ='bjobs %s'%(bid)
             status_info = os.popen(lsf_cmd)
             Status = self.openlava_job_status(status_info)
    
             if Status in exception_status:
               teststatus["%s_%s"%(i, seed)] =  0
             elif Status in onging_status: 
               continue
             elif Status == 'DONE':
               self.CheckResult(self.tasklist[i])
               teststatus[i] = testtasklist[i].result == 0 and 1 or 0

             if len(teststatus.keys()) == testtasklist.keys():
               break

             time.sleep(2)

    def RunTest(self):
        self.sema = threading.Semaphore(self.parallel_num)
        self.__taskstatus = {}
        if self.args.LSF:
          for i in self.tasklist:
            t=self.tasklist[i]
            if self.args.Category != None:
              if self.args.Category not in t.catgory: 
                 continue
            bid = self.openlava_submitter(t, i, "sim")
            self.bids.append(bid)
            setattr(self.tasklist[i], "bid", bid)
            sim_mon = threading.Thread(target=self.openlava_monitor, args=({}, {},  self.tasklist, self.__taskstatus, "sim"))
            sim_mon.setDaemon(True)
            sim_mon.start()
            sim_mon.join(2)

        else:
            __thread_lib=[]
            if len(self.tasklist.keys())>1:
               try:
                   for i in self.tasklist:
                       t=self.tasklist[i]
                       if self.args.Category != None:
                         if self.args.Category not in t.catgory: 
                            continue
                       self.sema.acquire()
                       __thread = threading.Thread(target=self.__DoSim, args=(t, self.sema, self.__grouptask, self.__taskstatus, i))
                       __thread_lib.append(__thread)
                       __thread.setDaemon(True)
                       __thread.start()

                   for t in __thread_lib:
                       t.join(2)
                       if not t.isAlive:
                          break
               except KeyboardInterrupt:
                   self.logger.info("Keyborad Interrupt Quit") 
                   sys.exit(1)
            else:
              name = self.tasklist.keys()[0]
              t = self.tasklist[name]
              self.__DoSim(t, self.sema, self.__grouptask, self.__taskstatus, t.name)

    def GetCmd(self, task, flag=0):
        __uvm_testname = task.uvm_testname.lstrip()
        __name=task.name.lstrip()
        __comp_dir = task.comp_dir.lstrip()
        __sim_dir = task.sim_dir.lstrip()
        __cov_dir = task.cov_dir.lstrip()
        __rtlfile = task.rtl_file.lstrip() 
        __tbfile = task.tb_file.lstrip() 
        __vipfile = task.vip_file.lstrip()
        __seed = str(task.seed).lstrip()
        if task.rtl_comp_opts == None:
          __rtl_compt_opt = ""
        else:
          __rtl_compt_opt = task.rtl_comp_opts.lstrip()
        if task.tb_comp_opts == None:
          __tb_compt_opt = ""
        else:
          __tb_compt_opt = task.tb_comp_opts.lstrip()
        if task.vip_comp_opts == None:
          __vip_compt_opt = ''
        else:
          __vip_compt_opt = task.vip_comp_opts.lstrip()
        if task.elab_comp_opts == None:
          __elab_compt_opt = "" 
        else:
          __elab_compt_opt = task.vip_comp_opts.lstrip()
        __tcl_file = task.tcl.strip()
        cmd = "make -f %s/Makefile "%(self.tools_home)
        if self.args.waveform:
            cmd+="verdi TEST='%s' RTL_FILELIST='%s' TB_FILELIST='%s' VIP_FILELIST='%s' COMP_DIR='%s' SIM_DIR='%s' "%(\
                __name, __rtlfile, __tbfile, __vipfile, __comp_dir, __sim_dir) 
        elif self.args.log:
            cmd+="log SIM_DIR=%s "%(\
                __sim_dir) 
        elif self.args.covmerge:
            cmd+="cov_merge COV_DIR=%s "%(\
                __cov_dir) 
        else:
            if self.args.clean:
                cmd+="clean COMP_DIR=%s "%(\
                    __comp_dir, __sim_dir) 
            
            do_compile = self.args.compile
            do_sim = self.args.sim

            if (not do_compile) and (not do_sim):
                if flag:
                    do_compile = True
                else:
                    do_sim = True

            if do_compile:
                cmd+="comp COMP_DIR='%s' RTL_FILELIST='%s' TB_FILELIST='%s' VIP_FILELIST='%s' \
                      RTL_COMP_OPTS='%s'  TB_COMP_OPTS='%s' VIP_COMP_OPTS='%s' ELAB_OPTS='%s'"%(\
                    __comp_dir, __rtlfile, __tbfile, __vipfile, __rtl_compt_opt, \
                    __tb_compt_opt, __vip_compt_opt, __elab_compt_opt) 
                print cmd
                if self.args.gls and self.args.Suite == "gls":
                    cmd+="GATE_SIM=on "
                if self.args.cov:
                    cmd+="COVERAGE=on COV_DIR=%s "%(__sim_dir)
                if self.args.cov_opt:
                    cmd+="COVERAGE_TYPE=%s "%(str(self.args.cov_opt))
                if self.args.quiet:
                    cmd += " QUIET=on "

            if do_sim:
                cmd+="sim COMP_DIR=%s SIM_DIR=%s SEED=%s UVM_TEST=%s TCL_FILE=%s"%(\
                    __comp_dir, __sim_dir, __seed, __uvm_testname, __tcl_file) 
                if hasattr(task, "ctest_name"):
                    if task.ctest_name == None:
                      cmd += ""
                    else:
                      cmd += " C_TEST=%s "%(task.ctest_name.lstrip())
                if hasattr(task, "cflags"):
                    if task.cflags == None:
                      cmd += ""
                    else:
                      cmd += " CTFLAGS=\'%s\' "%(task.cflags.lstrip())
                if hasattr(task, "tcl"):
                    cmd += " TCL_FILE=%s "%(task.tcl.lstrip())
                if hasattr(task, "sim_args"):
                    if task.sim_args == None:
                      cmd += ""
                    else:
                      cmd += " SIM_ARGS=\'%s\' "%(task.sim_args.lstrip())
                if hasattr(task, "uvm_timeout"):
                    cmd += " UVM_TIMEOUT=\'%s \'"%(task.uvm_timeout.lstrip())
                if self.args.fsdb:
                    cmd+=" FSDB_DUMP=on "
                else:
                    cmd+=" FSDB_DUMP=off "

                if self.args.gls:
                    cmd+="GATE_SIM=on "
                if self.args.cov:
                    cmd+="COVERAGE=on COV_DIR=%s "%(__sim_dir)
                if self.args.cov_opt:
                    cmd+="COVERAGE_TYPE=%s "%(str(self.args.cov_opt).lstrip())
                if self.args.quiet:
                    cmd+=" QUITE_MODE=on "

        if self.args.debug:
            self.logger.debug(cmd)
        return cmd

    def CheckResult(self, task):
        result= 0
        __sim_dir = task.sim_dir
        __sim_file = __sim_dir+"/sim.log"
        __pass_cfg = "%s/rules/%s"%(self.tools_home, task.pass_cfg.strip())
        __fail_cfg = "%s/rules/%s"%(self.tools_home, task.fail_cfg.strip())
        __ignore_cfg = "%s/rules/%s"%(self.tools_home, task.ignore_cfg.strip())
        #__pass_magic_key = " TEST PASS"
        #__sim_file_h = open(__sim_file, "r")
        #for line in __sim_file_h:
        #   if __pass_magic_key in 
        #      result = 1
        if self.args.debug:
          check_cmd = "python %s/%s -l %s -p %s -i %s -d"%(self.tools_home.strip(), task.checkfiles.strip(), 
                                                           __sim_file, __pass_cfg, __fail_cfg, __ignore_cfg)
        else:
          check_cmd = "python %s/%s -l %s -p %s -i %s "%(self.tools_home.strip(), task.checkfiles.strip(), 
                                                           __sim_file, __pass_cfg, __fail_cfg, __ignore_cfg)
        result=os.system(check_cmd)
        if result:
          setattr(task, "result", 0)
        else:
          setattr(task, "result", 1)
        #result=os.system(cmd)


    def PrintLog(self):
        while(True):
            acc = 1;
            if len(self.__taskstatus.keys()) == len(self.tasklist.keys()):
               for i in self.__taskstatus.keys():
                   acc *= self.__taskstatus[i]
               if acc:
                   break
               else:
                   time.sleep(2)
            else:
               time.sleep(2)

        log="""
**********************************************************************
                     Regression Result log
**********************************************************************"""
        for t in self.tasklist:
            i = self.tasklist[t] 
            if i.result: 
                log+="""
%s %s \033[32;1m PASS \033[0m"""%(i.name, i.seed)
            else:
                log+="""
%s %s\033[31;1m FAIL \033[0m"""%(i.name, i.seed)

        self.logger.info(log) 

if __name__ == "__main__":
  try:
    runsim=RunSim()
    runsim.Run()
    os._exit(0)
  except KeyboardInterrupt:
    for i in runsim.bids: 
      kill_cmd = "bkill %s"%(i)
      os.system(kill_cmd)
      runsim.logger.info("Kill all on-the fly task on the LSF")

  os._exit(0)
